package com.example.store.controller;

import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.store.common.BaseContext;
import com.example.store.common.IpUtil;
import com.example.store.common.Result;
import com.example.store.config.AlipayConfig;
import com.example.store.entity.*;
import com.example.store.entity.Record;
import com.example.store.service.GoodsService;
import com.example.store.service.OrderService;
import com.example.store.service.RecordService;
import com.example.store.service.TimeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.*;

@Controller
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private OrderService orderService;

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private RecordService recordService;

    @Autowired
    private TimeService timeService;

    @Resource
    JavaMailSenderImpl javaMailSender;

//    生成日志
    private void makeTime(String id, HttpServletRequest request, String operate){
        Time time = Time.createTime(id, 4);
        String ip = IpUtil.getIp(request);
        time.setIp(ip);
        time.setOperate(operate);
        timeService.save(time);
    }

//    添加订单
    @PostMapping("/add")
    @ResponseBody
    public Result<String> add(@RequestBody Order order, HttpServletRequest request){
//        用户校验
        String userId = BaseContext.getCurrentId();
        if(userId==null||(userId.charAt(0)!='u')){
            return Result.error("请登录");
        }
        Goods goods = goodsService.getById(order.getGoodsid());
        if(goods==null){
            return Result.error("无商品");
        }

//        保存
        order.setUserid(userId);
        order.setPrice(goods.getPrice());
        order.setName(goods.getName());
//        设定为未付款
        order.setStat(0);
        orderService.save(order);

//        记录日志
        makeTime(userId, request, "添加订单:"+order.getId());

        return Result.success("订单添加成功, 请尽快付款");
    }

//    分页
    @PostMapping("/page")
    @ResponseBody
    public Result<Page<Order>> page(@RequestBody Map<String, Integer> pageNum, HttpServletRequest request){
//        用户校验
        String userId = BaseContext.getCurrentId();
        if(userId==null||(userId.charAt(0)!='u')){
            return Result.error("请登录");
        }
        if(pageNum.get("pageNum")==null){
            return Result.error("无效页码");
        }

        Page<Order> pageInfo = new Page<>(pageNum.get("pageNum"), 10);
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Order::getUserid, userId);
        orderService.page(pageInfo, queryWrapper);

//        记录日志
        makeTime(userId, request, "订单分页");

        return Result.success(pageInfo);
    }

//    销售查看商品订单
    @PostMapping("/pageForGoods")
    @ResponseBody
    public Result<Page<Order>> pageForGoods(@RequestBody Map<String, String> pageNum, HttpServletRequest request){
//        用户校验
        String userId = BaseContext.getCurrentId();
        if(userId==null||(userId.charAt(0)!='s'&&!userId.equals("root"))){
            return Result.error("请销售员登录");
        }
        if(pageNum.get("pageNum")==null){
            return Result.error("无效页码");
        }
        if(pageNum.get("goodsid")==null){
            return Result.error("无商品");
        }
        Goods goods = goodsService.getById(pageNum.get("goodsid"));
        if(goods==null){
            return Result.error("错误的商品id");
        }
        if(!goods.getSeller().equals(userId)&&!userId.equals("root")){
            return Result.error("无权操作");
        }

//        按商品id查询
        Page<Order> pageInfo = new Page<>(Integer.parseInt(pageNum.get("pageNum")), 10);
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Order::getGoodsid, goods.getId());
        orderService.page(pageInfo, queryWrapper);

//        记录日志
        makeTime(userId, request, "订单分页");

        return Result.success(pageInfo);
    }

//    移除订单
    @PostMapping("/remove")
    @ResponseBody
    public Result<String> remove(@RequestBody Order order, HttpServletRequest request){
//        用户校验
        String userId = BaseContext.getCurrentId();
        if(userId==null||(userId.charAt(0)!='u')){
            return Result.error("请登录");
        }
        Order order1 = orderService.getById(order.getId());
        if(order1==null){
            return Result.error("无订单");
        }
        if(!order1.getUserid().equals(userId)){
            return Result.error("不是你的订单");
        }

        if(order1.getStat()!=0&&order1.getStat()!=2){
            return Result.error("已付款未到货或申诉中的订单不能删除");
        }

        orderService.removeById(order1.getId());

//        记录日志
        makeTime(userId, request, "移除订单:"+order1.getId());

        return Result.success("已删除");
    }

//    订单申诉(支付失败)
    @PostMapping("/error")
    @ResponseBody
    public Result<String> error(@RequestBody Order order, HttpServletRequest request){
//        用户校验
        String userId = BaseContext.getCurrentId();
        if(userId==null||(userId.charAt(0)!='u')){
            return Result.error("请登录");
        }
        Order order1 = orderService.getById(order.getId());
        if(order1==null){
            return Result.error("无订单");
        }
        if(!order1.getUserid().equals(userId)){
            return Result.error("不是你的订单");
        }

        if(order1.getStat()!=0){
            return Result.error("已付款或已到货的订单不能申诉");
        }

        Goods goods = goodsService.getById(order1.getGoodsid());
        //记录未处理订单数
        goods.setUnsend(goods.getUnsend()+1);
        goodsService.updateById(goods);

//        设为申诉中
        order1.setStat(3);
        orderService.updateById(order1);

//        记录日志
        makeTime(userId, request, "订单申诉:"+order1.getId());

        return Result.success("申诉中");
    }


//    发货
    @PostMapping("/send")
    @ResponseBody
    public Result<String> send(@RequestBody Order order, HttpServletRequest request){
//        用户校验
        String userId = BaseContext.getCurrentId();
        if(userId==null||userId.charAt(0)!='s'){
            return Result.error("请销售员登录");
        }
        Order order1 = orderService.getById(order.getId());
        if(order1==null){
            return Result.error("无订单");
        }
        Goods goods = goodsService.getById(order1.getGoodsid());
        if(!goods.getSeller().equals(userId)){
            return Result.error("不是你的商品");
        }
        if(order1.getStat()==0||order1.getStat()==2){
            return Result.error("未付款或已发货的订单无法发货");
        }

        if(goods.getCount()< order1.getCount()){
            return Result.error("库存不足");
        }

//        设为已发货
        order1.setStat(2);
        orderService.updateById(order1);

        //购买记录
        Record record = new Record();
        record.setDate(LocalDateTime.now());
        record.setType(1);
        record.setCount(order1.getCount());
        record.setGoodsid(order1.getGoodsid());
        record.setUserid(order1.getUserid());
        recordService.save(record);

        //更新商品销量
        goods.setSold(goods.getSold()+order1.getCount());
        goods.setCount(goods.getCount()-order1.getCount());
        goods.setUnsend(goods.getUnsend()>0? goods.getUnsend()-1 : 0);
        goodsService.updateById(goods);

//        记录日志
        makeTime(userId, request, "订单发货:"+order1.getId());

//        发邮件通知
        SimpleMailMessage mailMessage = new SimpleMailMessage();
        mailMessage.setSubject("发货通知");//主题
        mailMessage.setText("尊敬的"+order1.getUserid().substring(1)+"（id）, 您购买的"+order1.getName()+"已发货, 请注意签收\n感谢您的支持");//内容
        mailMessage.setTo(order1.getEmail());
        mailMessage.setFrom("cxh202030440133@163.com");
        javaMailSender.send(mailMessage);

        return Result.success("已发货");
    }

//    阿里支付跳转
    @RequestMapping(value = "/goAlipay", produces = {"text/html;charset=UTF-8"})
    @ResponseBody
    public String goAlipay(String orderId, HttpServletRequest request) throws Exception{

        Order order = orderService.getById(orderId);

        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);

        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

        //商户订单号，商户网站订单系统中唯一订单号，必填
        String out_trade_no = String.valueOf(order.getId());
        //付款金额，必填
        String total_amount = String.format("%.2f",order.getCount()*order.getPrice()/100.0).toString();
        //订单名称，必填
        String subject = order.getName();
        //商品描述，可空
        String body = "用户订购商品个数：" + order.getCount();

        // 该笔订单允许的最晚付款时间，逾期将关闭交易。取值范围：1m～15d。m-分钟，h-小时，d-天，1c-当天（1c-当天的情况下，无论交易何时创建，都在0点关闭）。 该参数数值不接受小数点， 如 1.5h，可转换为 90m。
        String timeout_express = "30m";

        alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
                + "\"total_amount\":\""+ total_amount +"\","
                + "\"subject\":\""+ subject +"\","
                + "\"body\":\""+ body +"\","
                + "\"timeout_express\":\""+ timeout_express +"\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        String userId = BaseContext.getCurrentId();
        makeTime(userId, request, "支付:"+orderId);

        //请求
        String result = alipayClient.pageExecute(alipayRequest).getBody();

        return result;
    }

//    阿里支付跳转回调，通过thymeleaf实现页面跳转、显示
    @RequestMapping(value = "/alipayReturnNotice")
    public String alipayReturnNotice(Model model, HttpServletRequest request) throws Exception {

        //获取支付宝GET过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map<String,String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); //调用SDK验证签名

        if(signVerified) {
            //商户订单号
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");

            //支付宝交易号
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");

            Order order = orderService.getById(out_trade_no);

            order.setStat(1);

            // 修改状态，改为支付成功，已付款;
            orderService.updateById(order);

            Goods goods = goodsService.getById(order.getGoodsid());
            //记录未处理订单数
            goods.setUnsend(goods.getUnsend()+1);
            goodsService.updateById(goods);

            model.addAttribute("order", order);

            return "alipaySuccess";

        }else {
            return "alipayError";
        }
    }

    //管理员分析用户画像

    //解析浏览行为
    @PostMapping("/analyzeRecord")
    @ResponseBody
    public Result<List<Order>> analyzeRecord(@RequestBody Order order){
//        用户校验
        String userId = BaseContext.getCurrentId();
        if(userId==null||!userId.equals("root")){
            return Result.error("请管理员登录");
        }

        LambdaQueryWrapper<Record> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(Record::getUserid, order.getUserid());
        //stat为0则查询浏览记录， stat为1则查询购买记录
        queryWrapper.eq(Record::getType, order.getStat());

//        按商品id排序
        queryWrapper.orderByAsc(Record::getGoodsid);
        queryWrapper.ge(Record::getDate, LocalDateTime.now().plusMonths(-1));
        List<Record> orders = recordService.list(queryWrapper);

//        由于是按商品id排序，可以通过一次遍历将不同商品的记录整合
        List<Order> orderList = new ArrayList<>();

        for(int i=0;i<orders.size();i++){
//            和当前商品id不同的新插入orderList，用count来存时间或者销量
            if(orderList.size()<1||(!orderList.get(orderList.size()-1).getGoodsid().equals(orders.get(i).getGoodsid()))){
                Order order1 = new Order();
                Goods goods = goodsService.getById(orders.get(i).getGoodsid());
                order1.setName(goods.getName());
                order1.setGoodsid(orders.get(i).getGoodsid());
                order1.setCount(order.getStat()==0?orders.get(i).getTime():orders.get(i).getCount());
                order1.setPrice(goods.getPrice());
                orderList.add(order1);
            }
//            相同的累加数值
            else{
                if(order.getStat()==0){
                    orderList.get(orderList.size()-1).setCount(orderList.get(orderList.size()-1).getCount()+orders.get(i).getTime());
                }
                else{
                    orderList.get(orderList.size()-1).setCount(orderList.get(orderList.size()-1).getCount()+orders.get(i).getCount());
                }
            }
        }

//        排序后返回
        orderList.sort(new Comparator<Order>() {
            @Override
            public int compare(Order o1, Order o2) {
                return Long.compare(o2.getCount(), o1.getCount());
            }
        });

        return Result.success(orderList);
    }

    //    用于管理员查询
    @PostMapping("/search")
    @ResponseBody
    public Result<Order> search(@RequestBody Order order){
        //        用户校验
        String userId = BaseContext.getCurrentId();
        if(userId==null||!userId.equals("root")){
            return Result.error("请管理员登录");
        }

        Order order1 = orderService.getById(order.getId());
        if(order1==null){
            return Result.error("无");
        }
        return Result.success(order1);
    }
}
